package jp.sourceforge.akjrcp.text_douga.rcp;

import com.akjava.lib.commons.text.TextUtils;
import com.akjava.lib.commons.video.VideoUtils;

import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.ITextOperationTarget;
import org.eclipse.jface.text.TextViewer;
import org.eclipse.jface.text.TextViewerUndoManager;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.events.VerifyListener;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.program.Program;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.ui.plugin.AbstractUIPlugin;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import jp.sourceforge.akjrcp.commons.ui.FileDirChoicer;
import jp.sourceforge.akjrcp.commons.ui.AbstractFileDirChoicer.FileStatusChangeEvent;
import jp.sourceforge.akjrcp.commons.ui.AbstractFileDirChoicer.FileStatusChangeListener;
import jp.sourceforge.akjrcp.commons.util.FileNameUtils;
import jp.sourceforge.akjrcp.ffmpeg.FFMpegCommandUtil;
import jp.sourceforge.akjrcp.ffmpeg.FFMpegJpegPipeWriter;
import jp.sourceforge.akjrcp.ffmpeg.FFMpegOptions;
import jp.sourceforge.akjrcp.ffmpeg.FFMpegUI;
import jp.sourceforge.akjrcp.ffmpeg.FFMpegUtils;
import jp.sourceforge.akjrcp.ffmpeg.ProcessListener;
import jp.sourceforge.akjrcp.ffmpeg.SimpleCommandExecuter;
import jp.sourceforge.akjrcp.text_douga.DougaLogger;
import jp.sourceforge.akjrcp.text_douga.DougaPreference;
import jp.sourceforge.akjrcp.text_douga.DougaSystem;
import jp.sourceforge.akjrcp.text_douga.Messages;
import jp.sourceforge.akjrcp.text_douga.SystemEnvironment;
import jp.sourceforge.akjrcp.text_douga.VideoOutInfo;
import jp.sourceforge.akjrcp.text_douga.parser.ParserUtils;
import jp.sourceforge.akjrcp.text_douga.parser.SimpleParser;
import jp.sourceforge.akjrcp.text_douga.video.DirectoryVideoWriter;
import jp.sourceforge.akjrcp.text_douga.video.PipedVideoWriter;
import jp.sourceforge.akjrcp.text_douga.views.syncsubimages.SyncSubImageView;
import jp.sourceforge.akjrcp.ui.FileOverwriteControler;
import jp.sourceforge.akjrcp.ui.RCPFileApplication;
import jp.sourceforge.akjrcp.util.ClipboardUtil;
import jp.sourceforge.akjrcp.util.DropFileListener;
import jp.sourceforge.akjrcp.util.DropFileMonitor;
import jp.sourceforge.akjrcp.util.ExecutingControler;
import jp.sourceforge.akjrcp.util.PrintWriterPrinter;
import jp.sourceforge.akjrcp.util.ExecutingControler.ExecutingControlButton;

import org.apache.commons.io.FileSystemUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class TextDougaView extends ViewPart {
	public static Log log=LogFactory.getLog(TextDougaView.class);
	
	public static final String ID = TextDougaView.class.getName();

	private TextDougaExecute textDougaExecute;
	private TextDougaApplication textDougaApplication;
	
	public static final String SEQUENCE_DIR="sequence";
	public static final String WORKING_DIR="temporary";
	public static final String DOWNLOADED_DIR="downloaded";
	
	private DougaLogger dougaLogger=new DougaLoggerImp();
	
	
	private boolean processVideo=true;
	private boolean processAudio=true;
	public static final int AVI=0;
	public static final int VIDEO_AUDIO=1;
	public static final int IMAGE_AUDIO=2;
	public static final int MODE_MUX=0;
	public static final int MODE_VIDEO=1;
	public static final int MODE_AUDIO=2;
	private int exportType;
	private boolean defaultProcessAudio=true;
	private boolean defaultProcessVideo=true;

	private TextViewerUndoManager undoMan;
	
	public String getText(){
		return dougaText.getTextWidget().getText();
	}
	public void setText(String text){
		 dougaText.getTextWidget().setText(text);
			textDougaApplication.setNeedSave(true);//modified;
			textDougaExecute.updateControlSwitch();
	}
	
	
	public class DougaLoggerImp implements DougaLogger{

		public void info(String logText) {
			log.info(logText);
			PlatformUI.getWorkbench().getDisplay().syncExec(new AddText(Messages.getString("log.info")+logText+"\r\n"));
		}

		public void trace(String logText) {
			log.trace(logText);
			PlatformUI.getWorkbench().getDisplay().syncExec(new AddText(Messages.getString("log.trace")+logText+"\r\n"));
			
		}

		public void warn(String logText) {
			log.warn(logText);
			PlatformUI.getWorkbench().getDisplay().syncExec(new AddText(Messages.getString("log.warn")+logText+"\r\n"));
			
		}

		public void error(String logText) {
			log.error(logText);
			PlatformUI.getWorkbench().getDisplay().syncExec(new AddText(Messages.getString("log.error")+logText+"\r\n"));	
		}
		
		
	}
	public class AddText extends Thread{
		private String text;
		public AddText(String text){
			this.text=text;
		}
		
		public void run(){
			String t=logText.getText();
			logText.setText(t+text);
			int last=t.length();
			logText.setSelection(last,logText.getText().length());
		}
		
	}
	@Override
	public void createPartControl(Composite parent) {
		Activator.getDefault().getPreferenceStore().getString("init");//just initialized preference store
		
		
		
		textDougaExecute=new TextDougaExecute();
		textDougaApplication=new TextDougaApplication();
		textDougaApplication.setOpenFilterExtensions(new String[]{"*.txt;.txtd"});
		textDougaApplication.setSaveFilterExtensions(new String[]{"*.txt",".txtd"});
		parent.setLayout(new GridLayout(2,false));
		
		Composite  dougaPanel=new Composite(parent,SWT.NULL);
		dougaPanel.setLayout(new GridLayout(8,false));
		createDougaActionButtons(dougaPanel);
		
		
		Composite  logPanel=new Composite(parent,SWT.NULL);
		logPanel.setLayout(new FillLayout());
		Label label=new Label(logPanel,SWT.NULL);
		label.setText("Log");
		
		Composite dougaTextMix=new Composite(parent,SWT.NULL);
		dougaTextMix.setLayoutData(new GridData(GridData.FILL_BOTH));
		dougaTextMix.setLayout(new GridLayout());
		
		fileNameText = new Text(dougaTextMix,SWT.BORDER|SWT.READ_ONLY);
		fileNameText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		
		dougaText =
            new TextViewer(dougaTextMix, SWT.H_SCROLL | 
                                      SWT.V_SCROLL | 
                                      SWT.BORDER);
		dougaText.getTextWidget().setLayoutData(new GridData(GridData.FILL_BOTH));
    Document doc = new Document("");
    dougaText.setDocument(doc);

    undoMan = new TextViewerUndoManager(999);
    dougaText.setUndoManager(undoMan);
    undoMan.connect(dougaText);

    dougaText.getTextWidget().addKeyListener(new KeyListener(){

		@Override
		public void keyPressed(KeyEvent e) {
			if((e.stateMask&SWT.CTRL)!=0){
			if(e.keyCode==(int)'z'){
				dougaText.doOperation(ITextOperationTarget.UNDO);
			    updateUndoRedo();
				e.doit=false;
			}else if(e.keyCode==(int)'y'){
		dougaText.doOperation(ITextOperationTarget.REDO);
	    updateUndoRedo();
		e.doit=false;
	}
			}
		}

		@Override
		public void keyReleased(KeyEvent e) {
			// TODO Auto-generated method stub
			
		}});
    dougaText.getTextWidget().addModifyListener(new ModifyListener(){

		@Override
		public void modifyText(ModifyEvent e) {
			log.info("text modified");
        	textDougaApplication.setNeedSave(true);//modified;
			textDougaExecute.updateControlSwitch();
                undoMan.endCompoundChange();
                updateUndoRedo();
		}
    	
    });
    dougaText.getTextWidget().addVerifyListener(new VerifyListener() {
            public void verifyText(VerifyEvent e) {
            //check
            }
    });

		
		DropFileMonitor monitor=new DropFileMonitor(dougaText.getTextWidget(),new DropFileListener(){

			public void dropFile(String[] arg0) {
				File file=null;
				for (int i = 0; i < arg0.length; i++) {
					File tmp=new File(arg0[i]);
					if(tmp.isFile() && (tmp.getName().toLowerCase().endsWith(".txt")||tmp.getName().toLowerCase().endsWith(".txtd"))){
						file=tmp;
						break;
						}
				}
				if(file!=null){
					textDougaApplication.openFile(file);	
				}else{
					for (int i = 0; i < arg0.length; i++) {
						File tmp=new File(arg0[i]);
						if(tmp.isFile()){
							int type=ParserUtils.getFileType(tmp.getName());
							if(type==ParserUtils.FILE_AUDIO||type==ParserUtils.FILE_IMAGE||type==ParserUtils.FILE_VIDEO||type==ParserUtils.FILE_SUBTTILE){
								insertFilePathLine(tmp);
							}
						}else{
							insertFilePathLine(tmp);//directory
						}
					}
				}
				
			}
			
		});
		
		
		
		
		logText = new Text(parent,SWT.BORDER|SWT.MULTI|SWT.V_SCROLL|SWT.WRAP);
		GridData gdata=new GridData(GridData.FILL_VERTICAL);
		gdata.widthHint=200;
		logText.setLayoutData(gdata);
		
		Composite  exportPanel=new Composite(parent,SWT.NULL);
		
		GridData g2=new GridData(GridData.FILL_HORIZONTAL);//important to expand
		g2.horizontalSpan=2;
		exportPanel.setLayoutData(g2);
		exportPanel.setLayout(new GridLayout(1,false));
		createDougaExportButtons(textDougaExecute,exportPanel);
		
		
//		
		textDougaExecute.updateControlSwitch();
		
		
		try {
			String dir=System.getProperty("user.dir");
			long check=1024*1024;
			long kbyte=FileSystemUtils.freeSpaceKb(dir);
			if(kbyte<check){
				dougaLogger.warn(jp.sourceforge.akjrcp.text_douga.rcp.Messages.getString("log.more_freespace"));
			}
		} catch (IOException e2) {
			// TODO Auto-generated catch block
			e2.printStackTrace();
		}
	}
	

	
	private void muxMode(){
		defaultProcessAudio=true;
		defaultProcessVideo=true;
		aviRadio.setEnabled(true);
		imageAudioRadio.setEnabled(true);
		videoAudioRadio.setEnabled(true);
	}
	
	private void videoMode(){
		defaultProcessAudio=false;
		defaultProcessVideo=true;
		aviRadio.setEnabled(true);
		imageAudioRadio.setEnabled(true);
		videoAudioRadio.setEnabled(true);
	}
	
	private void audioMode(){
		defaultProcessAudio=true;
		defaultProcessVideo=false;
		aviRadio.setEnabled(false);
		imageAudioRadio.setEnabled(false);
		videoAudioRadio.setEnabled(false);
	}
	
	private void createDougaExportButtons(TextDougaExecute executer,Composite composite){
		Composite muxRow=new Composite(composite,SWT.NULL);
		muxRow.setLayout(new GridLayout(4,false));
		
		ExecutingControlButton exec=new ExecutingControlButton(muxRow,SWT.NULL,executer,
				jp.sourceforge.akjrcp.text_douga.rcp.Messages.getString("textdouga.exec"),jp.sourceforge.akjrcp.text_douga.rcp.Messages.getString("textdouga.cancel"));
		GridData execData=new GridData();
		execData.widthHint=150;
		exec.setLayoutData(execData);
		
		muxRadio = new Button(muxRow,SWT.RADIO);
		muxRadio.setText(Messages.getString("textdouga.mux"));
		muxRadio.addSelectionListener(new SelectionListener(){
			public void widgetDefaultSelected(SelectionEvent e) {}
			public void widgetSelected(SelectionEvent e) {
				muxMode();
			}
		});
		muxRadio.setSelection(true);
		
		videoRadio = new Button(muxRow,SWT.RADIO);
		videoRadio.setText(Messages.getString("textdouga.video_only"));
		videoRadio.addSelectionListener(new SelectionListener(){
			public void widgetDefaultSelected(SelectionEvent e) {}
			public void widgetSelected(SelectionEvent e) {
				videoMode();
			}
		});
		audioRadio = new Button(muxRow,SWT.RADIO);
		audioRadio.setText(Messages.getString("textdouga.audio_only"));
		audioRadio.addSelectionListener(new SelectionListener(){
			public void widgetDefaultSelected(SelectionEvent e) {}
			public void widgetSelected(SelectionEvent e) {
				audioMode();
			}
		});
		Composite exportRow=new Composite(composite,SWT.NULL);
		exportRow.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		exportRow.setLayout(new GridLayout(4,false));
		
		Group textGroup=new Group(exportRow,SWT.NULL);
		GridData textData=new GridData(GridData.FILL_VERTICAL);
		textData.widthHint=100;
		textGroup.setLayoutData(textData);
		textGroup.setText(Messages.getString("textdouga.baseName"));
		textGroup.setToolTipText(Messages.getString("textdouga.baseName_tooltip"));
		textGroup.setLayout(new FillLayout());
		baseName = new Text(textGroup,SWT.NULL);
		baseName.setToolTipText(Messages.getString("textdouga.baseName_tooltip"));
		baseName.setText(jp.sourceforge.akjrcp.text_douga.rcp.Messages.getString("textdouga.default_export_video"));
		baseName.addModifyListener(new ModifyListener(){

			public void modifyText(ModifyEvent e) {
				updatePlayButton();
			}});
		
		outputFileChooser = new FileDirChoicer(exportRow,SWT.BORDER,FileDirChoicer.DIR,jp.sourceforge.akjrcp.text_douga.rcp.Messages.getString("textdouga.outputfile"));
		outputFileChooser.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		//outputFileChooser.setFilterExtensions(new String[]{"*.avi"});
		
		outputFileChooser.addFileListChangeListener(new FileSelected());
		//outputFileChooser.addFileListChangeListener(new OverwriteCheck());
		
		//default dir.
		//C:\tmp\betas\testdouga-0.2
	
		outputFileChooser.setFilePath(System.getProperty("user.dir"));
		textDougaExecute.addControl(outputFileChooser);
		
		Button openDir=new Button(exportRow,SWT.NULL);
		openDir.setImage(AbstractUIPlugin.imageDescriptorFromPlugin(
	    		"text_movie", "icons/showin.gif").createImage());
		openDir.setToolTipText(jp.sourceforge.akjrcp.text_douga.rcp.Messages.getString("textdouga.tooltip_opendir"));
		openDir.addSelectionListener(new SelectionListener(){

		public void widgetDefaultSelected(SelectionEvent e) {
			
		}

		public void widgetSelected(SelectionEvent event) {
			
			if(outputFileChooser.getFile()==null){
				return;
			}
			
			Runtime r=Runtime.getRuntime();
			try {
				r.exec(new String[]{"explorer",outputFileChooser.getFile().getAbsolutePath()});
			} catch (IOException e) {
				
				e.printStackTrace();
			}
		}
		
	});
		
		
		
		playButton = new Button(exportRow,SWT.NULL);
		playButton.setImage(AbstractUIPlugin.imageDescriptorFromPlugin(
	    		"text_movie", "icons/play.gif").createImage());
		playButton.setToolTipText(jp.sourceforge.akjrcp.text_douga.rcp.Messages.getString("textdouga.tooltip_play"));
		playButton.addSelectionListener(new SelectionListener(){

		public void widgetDefaultSelected(SelectionEvent e) {
			
		}

		public void widgetSelected(SelectionEvent event) {
			
			if(outputFileChooser.getFile()==null|| !outputFileChooser.getFile().exists()){
				return;
			}
			String aviPath=outputFileChooser.getAbsoluteFilePath()+"\\"+baseName.getText()+".avi";
			if(!new File(aviPath).exists()){
				return;
			}
			//launch is better
			Program.launch(aviPath);
			
		}
		
	});
		
		textDougaExecute.addControl(playButton);
		
		
		Composite typeRow=new Composite(composite,SWT.NULL);
		typeRow.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		typeRow.setLayout(new GridLayout(3,true));
		
		aviRadio = new Button(typeRow,SWT.RADIO);
		aviRadio.setText(Messages.getString("textdouga.export_avi"));
		aviRadio.addSelectionListener(new SelectionListener(){
			public void widgetDefaultSelected(SelectionEvent e) {}
			public void widgetSelected(SelectionEvent e) {
				exportType=AVI;
			}
		});
		
		videoAudioRadio = new Button(typeRow,SWT.RADIO);
		videoAudioRadio.setText(Messages.getString("textdouga.export_video_audio"));
		videoAudioRadio.addSelectionListener(new SelectionListener(){
			public void widgetDefaultSelected(SelectionEvent e) {}
			public void widgetSelected(SelectionEvent e) {
				exportType=VIDEO_AUDIO;
			}
		});
		
		imageAudioRadio = new Button(typeRow,SWT.RADIO);
		imageAudioRadio.setText(Messages.getString("textdouga.export_image_audio"));
		imageAudioRadio.addSelectionListener(new SelectionListener(){
			public void widgetDefaultSelected(SelectionEvent e) {}
			public void widgetSelected(SelectionEvent e) {
				exportType=IMAGE_AUDIO;
			}
		});
		aviRadio.setSelection(true);
		
		updatePlayButton();
	}
	
	public void setExportMode(int mode){
		if(mode==MODE_MUX){
			muxRadio.setSelection(true);
			videoRadio.setSelection(false);
			audioRadio.setSelection(false);
			muxMode();
		}else if(mode==MODE_VIDEO){
			muxRadio.setSelection(false);
			videoRadio.setSelection(true);
			audioRadio.setSelection(false);
			videoMode();
		}else if(mode==MODE_AUDIO){
			muxRadio.setSelection(false);
			videoRadio.setSelection(false);
			audioRadio.setSelection(true);
			audioMode();
		}
	}
	public void setExportType(int type){
		if(type==AVI){
			aviRadio.setSelection(true);
			videoAudioRadio.setSelection(false);
			imageAudioRadio.setSelection(false);
		}else if(type==VIDEO_AUDIO){
			aviRadio.setSelection(false);
			videoAudioRadio.setSelection(true);
			imageAudioRadio.setSelection(false);
		}else if(type==IMAGE_AUDIO){
			aviRadio.setSelection(false);
			videoAudioRadio.setSelection(false);
			imageAudioRadio.setSelection(true);
		}
		exportType=type;
	}
	
	private void pasteClipboard(){
		String text=ClipboardUtil.getCurrentText(PlatformUI.getWorkbench().getDisplay());
		if(text!=null){
			dougaText.getTextWidget().setText(text);

		}
	}
	private void createDougaActionButtons(Composite composite){
		Button newButton=new Button(composite,SWT.NULL);
		newButton.setImage(AbstractUIPlugin.imageDescriptorFromPlugin(
		    		"text_movie", "icons/text_new.gif").createImage());
		newButton.setToolTipText(jp.sourceforge.akjrcp.text_douga.rcp.Messages.getString("textdouga.tooltip_new"));
		newButton.addSelectionListener(new SelectionListener(){

			public void widgetDefaultSelected(SelectionEvent e) {
				
			}

			public void widgetSelected(SelectionEvent e) {
				textDougaApplication.newFile();
			}
			
		});
		
		Button openButton=new Button(composite,SWT.NULL);
		openButton.setImage(AbstractUIPlugin.imageDescriptorFromPlugin(
		    		"text_movie", "icons/opendir.gif").createImage());
		openButton.setToolTipText(jp.sourceforge.akjrcp.text_douga.rcp.Messages.getString("textdouga.tooltip_open"));
		openButton.addSelectionListener(new SelectionListener(){

			public void widgetDefaultSelected(SelectionEvent e) {
				
			}

			public void widgetSelected(SelectionEvent e) {
				textDougaApplication.openFile();
			}
			
		});
		
		Button pasteButton=new Button(composite,SWT.NULL);
		pasteButton.setImage(AbstractUIPlugin.imageDescriptorFromPlugin(
		    		"text_movie", "icons/text_paste.gif").createImage());
		pasteButton.setToolTipText(jp.sourceforge.akjrcp.text_douga.rcp.Messages.getString("textdouga.tooltip_paste"));
		pasteButton.addSelectionListener(new SelectionListener(){

			public void widgetDefaultSelected(SelectionEvent e) {
				
			}

			public void widgetSelected(SelectionEvent e) {
				pasteClipboard();
			}
			
		});
		
		
		saveButton = new Button(composite,SWT.NULL);
		saveButton.setImage(AbstractUIPlugin.imageDescriptorFromPlugin(
		    		"text_movie", "icons/text_save.gif").createImage());
		saveButton.setToolTipText(jp.sourceforge.akjrcp.text_douga.rcp.Messages.getString("textdouga.tooltip_save"));
		saveButton.addSelectionListener(new SelectionListener(){

			public void widgetDefaultSelected(SelectionEvent e) {
				
			}

			public void widgetSelected(SelectionEvent e) {
				boolean result=textDougaApplication.saveFile();
				log.info(result);
			}
			
		});
		saveButton.setEnabled(false);//first no xx.
		
		Button saveasButton=new Button(composite,SWT.NULL);
		saveasButton.setImage(AbstractUIPlugin.imageDescriptorFromPlugin(
		    		"text_movie", "icons/text_saveas.gif").createImage());
		saveasButton.setToolTipText(jp.sourceforge.akjrcp.text_douga.rcp.Messages.getString("textdouga.tooltip_saveas"));
		saveasButton.addSelectionListener(new SelectionListener(){

			public void widgetDefaultSelected(SelectionEvent e) {
				
			}

			public void widgetSelected(SelectionEvent e) {
				boolean result=textDougaApplication.saveAsFile();
				log.info(result);
			}
			
		});
		
		
		undoButton = new Button(composite,SWT.NULL);
		undoButton.setEnabled(false);
		undoButton.setText("Undo");
		undoButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				dougaText.doOperation(ITextOperationTarget.UNDO);
				 undoButton.setEnabled(undoMan.undoable());
		         redoButton.setEnabled(undoMan.redoable());
			}
		});
		
		redoButton = new Button(composite,SWT.NULL);
		redoButton.setText("Redo");
		redoButton.setEnabled(false);
		redoButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				dougaText.doOperation(ITextOperationTarget.REDO);
				 undoButton.setEnabled(undoMan.undoable());
		         redoButton.setEnabled(undoMan.redoable());
			}
		});
		
		Button synsubButton = new Button(composite,SWT.NULL);
	
		synsubButton.setText("Syncsub");
		synsubButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				String text=dougaText.getTextWidget().getText();
				if(text.length()>0){
					SyncSubImageView view=(SyncSubImageView) PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().findView(SyncSubImageView.ID);
					view.loadText(text.replace("\r\n","\n"));
					PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().activate(view);
				}
			}
		});
	}

	@Override
	public void setFocus() {
		// TODO Auto-generated method stub
		
	}
	
	private String outputPath;
	private String dText;
	private File iFile;

	private FileDirChoicer outputFileChooser;

	private TextViewer dougaText;

	private Text logText;

	private Button saveButton;

	private Text fileNameText;

	private Text baseName;

	private Button imageAudioRadio;

	private Button videoAudioRadio;

	private Button aviRadio;

	private Button playButton;

	private Button muxRadio;

	private Button videoRadio;

	private Button audioRadio;

	private Button undoButton;

	private Button redoButton;
	public class TextDougaExecute extends ExecutingControler{

		private SimpleCommandExecuter simpleExecuter;
		private SimpleParser parser;
		private BufferedOutputStream bout;

		private File workingDir;

		private boolean deleteSequences=true;//debug TODO before check true you shoud your type setting?
		private String baseFileName;
		public void afterExecute() {
			simpleExecuter=null;
			parser=null;
			bout=null;
			
			log.info("delete workdir"+workingDir);//TODO keep resource
		
			if(deleteSequences){
				clearExportDir();
			}
			
			updatePlayButton();//for play
		}

		public void beforeExecute() {
			log.info("beforeExecute");
			baseFileName=baseName.getText();
			outputPath=outputFileChooser.getAbsoluteFilePath();
			dText=dougaText.getTextWidget().getText();
			iFile=textDougaApplication.getFile();
			log.info(iFile);
			log.info(dText);
		}

		public boolean canExecute() {
			//log.info("text:"+dougaText.getTextWidget().getText());
			if(!outputFileChooser.getAbsoluteFilePath().equals("")&&dougaText.getTextWidget().getText().length()>0){
				return true;
			}
			return false;
		}

		public void cancelExecuting() {
			DougaSystem.cancelling=true;
			
			if(parser!=null){
				parser.setCancelling(true);
			}
			
			
			//cancell audio
			if(bout!=null){
				try {
					bout.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			
			//cancel simple executer
			if(simpleExecuter!=null){
			Process process=simpleExecuter.getProcess();
			if(process!=null){
				process.destroy();
			}
			}
		}

		public void clearExportDir(){
			if(workingDir!=null){
				String v[]=workingDir.list();
				if(v!=null){
				for (int i = 0; i < v.length; i++) {
					if(v[i].endsWith(".jpg") || v[i].endsWith(".pcm")){
					new File(workingDir,v[i]).delete();
					}else if(v[i].endsWith(".avi")){
					new File(workingDir,v[i]).delete();
					}else{
						log.info("other remain:"+v[i]);
					}
				}
				}
				}
		}

		public void inExecute(){
			//initialize
			encodeFinished=false;
			encodeStarted=false;
			
			long startTime=System.currentTimeMillis();
			DougaSystem.setDougaLogger(dougaLogger);
			//String originalFFMpeg=PlatformUI.getPreferenceStore().getString(FFMpegUI.FFMPEG_PATH);
			//String pureFFMpeg=PlatformUI.getPreferenceStore().getString(FFMpegUI.PURE_FFMPEG_PATH);
			String finalReport="";
			
			
			//log.trace(System.getProperty("user.dir")+";"+System.getProperty("user.home"));
			//String ffmpegPath=FFMpegUI.getFFmpegOrPureFFMpeg();
			String ffmpegPath=FFMpegUI.getFFmpegOrPureFFMpeg();
			if(ffmpegPath==null){
				dougaLogger.error(jp.sourceforge.akjrcp.text_douga.rcp.Messages.getString("log.no_ffmpeg"));
				dougaLogger.info(Messages.getString("log.cancelled"));
				return;
			}
			
			String trueFFMpegPath=FFMpegUI.getFFmpeg();
			
			String videoCodec=Activator.getDefault().getPreferenceStore().getString(TextDougaAviPage.AVI_VIDEO_CODEC);
			String audioCodec=Activator.getDefault().getPreferenceStore().getString(TextDougaAviPage.AVI_AUDIO_CODEC);
			
			log.info(videoCodec);
			log.info(audioCodec);
			
			//when use pure_ffmpeg.exe
			if(!ffmpegPath.equals(trueFFMpegPath)){
				boolean error=false;;
				if(!FFMpegUI.isPureFFMpegSupportedVideoCodec(videoCodec)){
					dougaLogger.warn(jp.sourceforge.akjrcp.text_douga.rcp.Messages.getString("log.not_supported_video"));
					error=true;
				}
				if(!FFMpegUI.isPureFFMpegSupportedAudioCodec(audioCodec)){
					dougaLogger.warn(jp.sourceforge.akjrcp.text_douga.rcp.Messages.getString("log.not_supported_audio"));
				}
				
				if(error){
					DougaSystem.dougaLogger.info(Messages.getString("log.cancelled"));
					return;
				}
				
			}
			String fpsv=Activator.getDefault().getPreferenceStore().getString(TextDougaPage.VIDEO_FPS);
			double fps=30;
			if(!fpsv.equals("")){
				if(fpsv.equals(TextDougaPage.VIDEO_FPS_OTHER)){
					fpsv=Activator.getDefault().getPreferenceStore().getString(TextDougaPage.VIDEO_FPS_OTHER);
					}
				try{
				fps=Double.parseDouble(fpsv);
				}catch(Exception e){
					DougaSystem.dougaLogger.warn(Messages.getString("textdouga_wrong_fps"));
					fps=30;
				}
			}
		
			String size=Activator.getDefault().getPreferenceStore().getString(TextDougaPage.VIDEO_SIZE);
			if(size.equals(TextDougaPage.VIDEO_SIZE_OTHER)){
				size=Activator.getDefault().getPreferenceStore().getString(TextDougaPage.VIDEO_SIZE_OTHER);
			}
			
			int w_h[]=null;
			try{
			w_h=VideoUtils.sizeToWidthHeight(size);
			}catch(Exception e){}
			if(w_h==null){
				DougaSystem.dougaLogger.warn(Messages.getString("textdouga_wrong_size"));
				w_h=new int[]{320,240};
			}
			
			String youtubeDLPath=PlatformUI.getPreferenceStore().getString("youtubedl.path_youtubedl.exe");;
			String youtubeDLPyPath=PlatformUI.getPreferenceStore().getString("youtubedl.path_youtubedl.py");
			String pythonPath=PlatformUI.getPreferenceStore().getString("youtubedl.path_python");
			
			if(youtubeDLPath.equals("") && (youtubeDLPyPath.equals("") || pythonPath.equals(""))){
				dougaLogger.warn(jp.sourceforge.akjrcp.text_douga.rcp.Messages.getString("log.no_youtubedl"));
			}
			
			
			String dir=System.getProperty("user.dir")+"\\"+WORKING_DIR;
			File downloaded=new File(dir,DOWNLOADED_DIR);
			workingDir=new File(dir,SEQUENCE_DIR);
			workingDir.mkdirs();
			clearExportDir();
			
			
			
			
			File pcm=new File(workingDir,"audio.pcm");
			File workingAvi=new File(workingDir,"video.avi");
			//File wav=new File(workingDir,"audio.wav");
			
			if(baseFileName.equals("")){
				baseFileName=jp.sourceforge.akjrcp.text_douga.rcp.Messages.getString("textdouga.default_export_video");
			}
			File outputVideo=new File(outputPath,baseFileName+".avi");
			//check valid
			String audioExtension=FFMpegUtils.audioCodecToExtension(audioCodec);
			if(audioExtension==null){
				log.warn("invalid audioCodec:"+audioCodec);
				DougaSystem.dougaLogger.info("invalid audioCodec:"+audioCodec);
				DougaSystem.dougaLogger.info(Messages.getString("log.cancelled"));
				return;
			}
			File outputAudio=new File(outputPath,baseFileName+"."+audioExtension);
			
			long l=System.currentTimeMillis()/1000;
			
			File tmpVideoOutput=new File(outputVideo.getParent(),l+"_"+outputVideo.getName());
			File tmpAudioOutput=new File(outputVideo.getParent(),l+"_"+outputAudio.getName());
			
			/*
			log.info(outputVideo);
			boolean deleteOut=outputVideo.delete();//some application only reserve delete
			//System.out.println("delete:"+deleteOut);
			if(outputVideo.exists()){
				dougaLogger.error("Delete faild:"+outputPath);
				
				return;
			}
			try {
				FileUtils.touch(tmpVideoOutput);
			} catch (IOException e1) {
				dougaLogger.error("write faild:"+outputPath);
				
				
				e1.printStackTrace();
				return;
			}*/
			
			//clear cashe otherwise using old images.
			SystemEnvironment.getSystemEnvironment().getImageCasher().clear();
			
			DougaPreference dougaPreference=new DougaPreference();
			//both of these are default value from settings
			dougaPreference.setFps(fps);
			dougaPreference.setWidth(w_h[0]);
			dougaPreference.setHeight(w_h[1]);
			dougaPreference.setFfmpegPath(ffmpegPath);
			
			log.info("wh="+dougaPreference.getWidth()+","+dougaPreference.getHeight());
			
			String fpath="";
			parser = new SimpleParser(ffmpegPath,downloaded,null,youtubeDLPath);
			File inputDir=new File(System.getProperty("user.dir"));//for no file
			if(iFile!=null){//on file
				inputDir=iFile.getParentFile();//root
				fpath=iFile.getAbsolutePath();
				}
			
			DougaSystem.setDougaLogger(dougaLogger);
			dougaLogger.trace(Messages.getString("log.start_text_douga")+" "+fpath);
			DougaSystem system=null;
			try {
				system = parser.parseTextDouga(dText,inputDir,dougaPreference);
				fps=system.getVideoSystem().getDougaPreference().getFps();//update
				if(system==null){
					log.info("System is null");
					DougaSystem.dougaLogger.info(Messages.getString("log.cancelled"));
					return;
				}
			} catch (IOException e1) {
				DougaSystem.dougaLogger.warn(e1.getMessage());
				
				e1.printStackTrace();
				DougaSystem.dougaLogger.info(Messages.getString("log.cancelled"));
				return;
			}
			log.info("parse finished:"+" fps="+fps+",w="+system.getVideoSystem().getDougaPreference().getWidth()+" height="+system.getVideoSystem().getDougaPreference().getHeight());
			
			processVideo=defaultProcessVideo;
			processAudio=defaultProcessAudio;
			
			if(system.getVideoSystem().getVideoDatas().length==0){
				dougaLogger.warn(Messages.getString("log.novideo"));
				//DougaSystem.dougaLogger.info(Messages.getString("log.cancelled"));
				//return;
				processVideo=false;
			}
			
			if(system.getAudioSystem().getAudioDatas().length==0){
				dougaLogger.warn(Messages.getString("log.noaudio"));
				//DougaSystem.dougaLogger.info(Messages.getString("log.cancelled"));
				//return;
				processAudio=false;
			}
			
			if(processVideo==false && processAudio==false){
				//do nothing.
				DougaSystem.dougaLogger.info(Messages.getString("log.nothing_todo"));
				return;
			}
			IPreferenceStore store=Activator.getDefault().getPreferenceStore();
			
			
			
			if(isCanceling()){
				DougaSystem.dougaLogger.info(Messages.getString("log.cancelled"));
				return;
			}
			
			ConvertResult convertResult=null;
			if(exportType==IMAGE_AUDIO){
				//for avoid overwrite.
				
				File imageExportDir=new File(outputPath,baseFileName);
				if(processVideo){
					File oldDir=new File(outputPath,baseFileName);
					if(oldDir.exists()){
						String newName=FileNameUtils.getNotFoundFileName(oldDir);
						boolean r=oldDir.renameTo(new File(newName));
						if(!r){
							DougaSystem.dougaLogger.warn(Messages.getString("log.dir_rename_faild"));
						}
					}
					
				imageExportDir.mkdir();
					if(!imageExportDir.exists()){
					log.info("can't make dir "+imageExportDir);
					DougaSystem.dougaLogger.info(Messages.getString("log.cancelled"));
					return;
					}
					finalReport+=Messages.getString("textdouga.image_dir")+":"+imageExportDir.getName()+"\r\n";
				}
				
				convertResult=convertImageBased(system,ffmpegPath,pcm,fps,videoCodec,audioCodec,imageExportDir,store);
				if(convertResult==null){
					DougaSystem.dougaLogger.info(Messages.getString("log.cancelled"));
					return;
				}
				if(!convertResult.isSuccessed()){
					//faild
					log.info("image faild");
					DougaSystem.dougaLogger.info(Messages.getString("log.cancelled"));
					return;
				}
			}
			else if(Activator.getDefault().getPreferenceStore().getBoolean(TextDougaPage.USE_HIGHSPEED)){
				convertResult=convertSpeedBased(system,ffmpegPath,pcm,fps,videoCodec,audioCodec,workingAvi,store);
				if(convertResult==null){
					//canceldExecute();
					DougaSystem.dougaLogger.info(Messages.getString("log.cancelled"));
					return;
				}
				if(!convertResult.isSuccessed()){
					//faild
					log.info("high speed faild");
					DougaSystem.dougaLogger.info(Messages.getString("log.cancelled"));
					return;
				}
			}else{
				convertResult=convertQualityBased(system,ffmpegPath,pcm,fps,videoCodec,audioCodec,tmpVideoOutput);
				if(convertResult==null){
					DougaSystem.dougaLogger.info(Messages.getString("log.cancelled"));
					return;
				}
				if(!convertResult.isSuccessed()){
					//faild
					log.info("quality faild");
					DougaSystem.dougaLogger.info(Messages.getString("log.cancelled"));
					return;
				}
			}
			
			log.info("convertResult:video="+convertResult.getVideoPath());
			log.info("convertResult:audio="+convertResult.getAudioPath());
			
			//now ignore ,because sometime cancel happend.
			/*
			boolean notfound=false;
			if(convertResult.getVideoPath()!=null && !new File(convertResult.getVideoPath()).exists()){
				notfound=true;
				log.warn("video not found");
			}
			if(convertResult.getAudioPath()!=null && !new File(convertResult.getAudioPath()).exists()){
				notfound=true;
				log.warn("audio not found");
			}
			if(notfound){
				DougaSystem.dougaLogger.info(Messages.getString("log.cancelled"));
				return;
			}
			
			//switch case
			if(convertResult.getVideoPath()==null && convertResult.getAudioPath()==null){
				log.warn("never happend");
				DougaSystem.dougaLogger.info(Messages.getString("log.cancelled"));
				return;
			}
			*/
			
			//final release movies
			if(convertResult.getVideoPath()==null && convertResult.getAudioPath()!=null){
			//process Audio only
				if(convertResult.getAudioPath()!=null){
					encodeAudio(ffmpegPath,convertResult.getAudioPath(),audioCodec,store,tmpAudioOutput);
					}
			}else if(exportType==AVI){
				//mux video and audio.
				File file=new File(convertResult.getVideoPath());
				String ffcommand[]=null;
				//high speed mode
				if(file.isFile()){
					if(convertResult.getAudioPath()==null){
						//just rename
						boolean r=false;
						for(int i=0;i<4*30;i++){//sometime has deley
						r=workingAvi.renameTo(tmpVideoOutput);
						log.info("tried rename:"+(i+1));
						try {
							Thread.sleep(250);
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						if(r){
							break;
							}
						}
						if(r==false){
							log.warn("avi:rename faild:"+tmpVideoOutput);
							DougaSystem.dougaLogger.info(Messages.getString("log.cancelled"));
							return;
							}
					}else{
						
						dougaLogger.trace(Messages.getString("log.muxing_videos"));
						//String options[]={"-b",store.getString(TextDougaAviPage.VIDEO_BITRATE)+"k","-ab",store.getString(TextDougaAviPage.AUDIO_BITRATE)+"k","-ar",store.getString(TextDougaAviPage.AUDIO_RATE),"-ac",store.getString(TextDougaAviPage.AUDIO_CHANNEL)};
						ffcommand=FFMpegCommandUtil.makeMuxPCMAndVideoCommand(ffmpegPath, convertResult.getVideoPath(),convertResult.getAudioPath(),"copy",audioCodec,new String[]{"-ab",store.getString(TextDougaAviPage.AUDIO_BITRATE)+"k","-ar",store.getString(TextDougaAviPage.AUDIO_RATE),"-ac",store.getString(TextDougaAviPage.AUDIO_CHANNEL)},tmpVideoOutput.getAbsolutePath() );//todo ,"-shortest"
						
						
					}
				
				}else{
				dougaLogger.trace(Messages.getString("log.muxing_videos"));
				
				String options[];
				
				if(videoCodec.equals(FFMpegOptions.CODEC_VIDEO_XVID)){
					options=new String[]{"-b",store.getString(TextDougaAviPage.VIDEO_BITRATE)+"k","-vtag","XVID","-ab",store.getString(TextDougaAviPage.AUDIO_BITRATE)+"k","-ar",store.getString(TextDougaAviPage.AUDIO_RATE),"-ac",store.getString(TextDougaAviPage.AUDIO_CHANNEL)};//todo ,"-shortest"
					
						
				}else{
				options=new String[]{"-b",store.getString(TextDougaAviPage.VIDEO_BITRATE)+"k","-ab",store.getString(TextDougaAviPage.AUDIO_BITRATE)+"k","-ar",store.getString(TextDougaAviPage.AUDIO_RATE),"-ac",store.getString(TextDougaAviPage.AUDIO_CHANNEL)};//todo ,"-shortest"
				
				}
				ffcommand=FFMpegCommandUtil.makeJpegInputCommand(ffmpegPath, convertResult.getVideoPath(), "", 5, ".jpg", ""+fps, convertResult.getAudioPath(),videoCodec,audioCodec,options,tmpVideoOutput.getAbsolutePath() );
				}
				
				if(ffcommand!=null){
				for (int i = 0; i < ffcommand.length; i++) {
					System.out.print("\""+ffcommand[i]+"\""+" ");
				}
				PrintWriterPrinter printer=new PrintWriterPrinter(System.out);
				simpleExecuter=new SimpleCommandExecuter(ffcommand);
				simpleExecuter.setPrinter(printer);
				simpleExecuter.execute();
				}
				
			}else if(exportType==VIDEO_AUDIO){
				//video is image ,do encode
//				mux video and audio.
				File file=new File(convertResult.getVideoPath());
				String ffcommand[]=null;
				//high speed mode
				if(file.isFile()){
				//just rename
				boolean r=false;
				for(int i=0;i<4*30;i++){
				r=workingAvi.renameTo(tmpVideoOutput);
				log.info("tried rename:"+(i+1));
				try {
					Thread.sleep(250);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				if(r){
					break;
					}
				}
				if(r==false){
					log.warn("video_audio:rename faild:"+tmpVideoOutput);
					DougaSystem.dougaLogger.info(Messages.getString("log.cancelled"));
					return;
					}
				
				if(convertResult.getAudioPath()!=null){
					
					encodeAudio(ffmpegPath,convertResult.getAudioPath(),audioCodec,store,tmpAudioOutput);
					}
				
				}else{
				//only directory call ffmpeg command
				dougaLogger.trace(Messages.getString("log.muxing_videos"));
				
				String options[]={"-b",store.getString(TextDougaAviPage.VIDEO_BITRATE)+"k","-ab",store.getString(TextDougaAviPage.AUDIO_BITRATE)+"k","-ar",store.getString(TextDougaAviPage.AUDIO_RATE),"-ac",store.getString(TextDougaAviPage.AUDIO_CHANNEL)};
				ffcommand=FFMpegCommandUtil.makeJpegInputCommand(ffmpegPath, convertResult.getVideoPath(), "", 5, ".jpg", ""+fps, null,videoCodec,audioCodec,options,tmpVideoOutput.getAbsolutePath() );
				for (int i = 0; i < ffcommand.length; i++) {
					System.out.print("\""+ffcommand[i]+"\""+" ");
				}
				PrintWriterPrinter printer=new PrintWriterPrinter(System.out);
				simpleExecuter=new SimpleCommandExecuter(ffcommand);
				simpleExecuter.setPrinter(printer);
				simpleExecuter.execute();
				}
				
				//encode audio
				
				if(isCanceling()){
					DougaSystem.dougaLogger.info(Messages.getString("log.cancelled"));
					return;
				}
				
				if(convertResult.getAudioPath()!=null){
					encodeAudio(ffmpegPath,convertResult.getAudioPath(),audioCodec,store,tmpAudioOutput);
					}
			}else if(exportType==IMAGE_AUDIO){
				//video already done.
				
				//encode audio
				if(convertResult.getAudioPath()!=null){
					encodeAudio(ffmpegPath,convertResult.getAudioPath(),audioCodec,store,tmpAudioOutput);
					}
			}
			
			
			if(isCanceling()){
				DougaSystem.dougaLogger.info(Messages.getString("log.cancelled"));
				return;
			}
			
			
			//rename files.
			dougaLogger.trace(Messages.getString("log.finished")+"\r\n");
			boolean faild=false;
			if(processVideo && exportType!=IMAGE_AUDIO){//IMAGE is folder
			if(outputVideo.exists()){
				String newName=FileNameUtils.getNotFoundFileName(outputVideo);
				outputVideo.renameTo(new File(newName));
			}
			boolean b=tmpVideoOutput.renameTo(outputVideo);
			
			if(!b){
				dougaLogger.error(Messages.getString("log.rename_faild")+":"+tmpVideoOutput);
				faild=true;
				finalReport+=Messages.getString("textdouga.video_file")+":"+tmpVideoOutput.getName()+"\r\n";
			}else{
				finalReport+=Messages.getString("textdouga.video_file")+":"+outputVideo.getName()+"\r\n";
			}
			}
			
			//when there are audio file
			if(processAudio && (exportType!=AVI || !processVideo)){
				//rename old ones
				if(outputAudio.exists()){
					String newName=FileNameUtils.getNotFoundFileName(outputAudio);
					outputAudio.renameTo(new File(newName));
					
				}
				
				boolean b=tmpAudioOutput.renameTo(outputAudio);
				
				if(!b){
					dougaLogger.error(Messages.getString("log.rename_faild")+":"+tmpAudioOutput);
					faild=true;
					finalReport+=Messages.getString("textdouga.audio_file")+":"+tmpAudioOutput.getName()+"\r\n";
				}else{
					finalReport+=Messages.getString("textdouga.audio_file")+":"+outputAudio.getName()+"\r\n";
					}
				}
			
			dougaLogger.trace(finalReport);
			
			long end=System.currentTimeMillis();
			int sec=(int) ((end-startTime)/1000);
			dougaLogger.info(jp.sourceforge.akjrcp.text_douga.rcp.Messages.getString("textdouga.complete")+" time: "+sec+" sec"+"\r\n");
			if(faild){
				//when faild?
				return;
			}
			
			
			
		}
		private void encodeAudio(String ffmpegPath,String pcmPath,String audioCodec,IPreferenceStore store,File finalOutput){
			String options[]=FFMpegCommandUtil.makePCMInputCommand(ffmpegPath,pcmPath,audioCodec,new String[]{"-ab",store.getString(TextDougaAviPage.AUDIO_BITRATE)+"k","-ar",store.getString(TextDougaAviPage.AUDIO_RATE),"-ac",store.getString(TextDougaAviPage.AUDIO_CHANNEL)},finalOutput.getAbsolutePath());
			PrintWriterPrinter printer=new PrintWriterPrinter(System.out);
			simpleExecuter=new SimpleCommandExecuter(options);
			simpleExecuter.setPrinter(printer);
			simpleExecuter.execute();
		}
		
		boolean encodeStarted;
		boolean encodeFinished;
		private ConvertResult convertSpeedBased(DougaSystem system,String ffmpegPath,File pcm,double fps,String videoCodec,String audioCodec,File tmpOutput,IPreferenceStore store){
			log.info("start convertSpeedBased");
			ConvertResult converResult=new ConvertResult();
			
			log.warn("encodeStarted:"+encodeStarted);
			
			try {
				
				if(processVideo){
					dougaLogger.trace(Messages.getString("log.create_video_sequence"));
				String[] options;
				if(videoCodec.equals(FFMpegOptions.CODEC_VIDEO_XVID)){
					options=new String[]{"-vcodec",videoCodec,"-b",store.getString(TextDougaAviPage.VIDEO_BITRATE)+"k","-vtag","XVID","-an"};
						
				}else{
				options=new String[]{"-vcodec",videoCodec,"-b",store.getString(TextDougaAviPage.VIDEO_BITRATE)+"k","-an"};
				}
				FFMpegJpegPipeWriter ffwriter=new FFMpegJpegPipeWriter(ffmpegPath,true,new String[]{"-r",""+fps},options,tmpOutput.getAbsolutePath());
				//ffwriter.setProcessPrinter(null);
				ffwriter.setProcessListener(new ProcessListener(){

					public void finished() {
						encodeFinished=true;
					}

					public void started() {
						encodeStarted=true;
					}});
				
				new Thread(ffwriter).start();
				
				//need time out.//TODO
				long waitStart1=System.currentTimeMillis();
				while(!encodeStarted){
					try {
						Thread.sleep(100);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					if(System.currentTimeMillis()>waitStart1+1000*30){//wait 30;
						log.warn("faild started");
						break;
					}
					log.info("wait start");
				}
				log.info("video write");
				PipedVideoWriter videoWriter=new PipedVideoWriter(system.getVideoSystem().getDougaPreference(),ffwriter.getJpegPipeWriter(),workingDir);
				videoWriter.setItemDatas(system.getVideoSystem().getSortedItemDatas());
				videoWriter.setEffectDatas(system.getVideoSystem().getEffectDatas());
				
				VideoOutInfo[] infos=system.getVideoSystem().writeDatas(videoWriter);
				converResult.setVideoPath(tmpOutput.getAbsolutePath());
				
				long maxwait=1000*30;
				long waitStart=System.currentTimeMillis();
				while(!encodeFinished){
					if(isCanceling()){
						return null;
					}
					try {
						Thread.sleep(250);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					log.info("wait finish");
					if(waitStart+maxwait<System.currentTimeMillis()){
						log.warn("over time wait finish:maybe cancelled");
						break;
					}
				}
				
				//wait file more
				while(!tmpOutput.exists()){
					if(isCanceling()){
						return null;
					}
					try {
						Thread.sleep(100);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					log.info("wait finish file");
					if(waitStart+maxwait<System.currentTimeMillis()){
						log.warn("over time wait finish:maybe cancelled");
						break;
					}
				}
				}
				
				
				
				
				
				if(processAudio){
					if(isCanceling()){
						//DougaSystem.dougaLogger.info(Messages.getString("log.cancelled"));
						return null;
					}
					dougaLogger.trace(Messages.getString("log.create_audio_sequence"));
				FileOutputStream aout=new FileOutputStream(pcm);
				system.getAudioSystem().writeDatas(aout);
				converResult.setAudioPath(pcm.getAbsolutePath());
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				canceldExecute();
				return null;
			}
			
			encodeStarted=false;
			converResult.setSuccessed(true);
			return converResult;
		}
		
		private ConvertResult convertImageBased(DougaSystem system,String ffmpegPath,File pcm,double fps,String videoCodec,String audioCodec,File exportDir,IPreferenceStore store){
			ConvertResult converResult=new ConvertResult();
			
			
			try {
				
				if(processVideo){
					DirectoryVideoWriter videoWriter=new DirectoryVideoWriter(exportDir,workingDir);
				
				dougaLogger.trace(Messages.getString("log.create_video_sequence"));
				VideoOutInfo[] infos=system.getVideoSystem().writeDatas(videoWriter);
				dougaLogger.trace(Messages.getString("log.insert_item_and_effect"));
				system.getVideoSystem().writeItemAndEffect(videoWriter.getExportDir(), infos);
				converResult.setVideoPath(exportDir.getAbsolutePath());
				}
				
				if(processAudio){
					dougaLogger.trace(Messages.getString("log.create_audio_sequence"));
				FileOutputStream aout=new FileOutputStream(pcm);
				system.getAudioSystem().writeDatas(aout);
				converResult.setAudioPath(pcm.getAbsolutePath());
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			encodeStarted=false;
			converResult.setSuccessed(true);
			return converResult;
		}
		public class ConvertResult{
			private String videoPath;
			private String audioPath;
			private boolean successed;
			public String getAudioPath() {
				return audioPath;
			}
			public void setAudioPath(String audioPath) {
				this.audioPath = audioPath;
			}
			public boolean isSuccessed() {
				return successed;
			}
			public void setSuccessed(boolean successed) {
				this.successed = successed;
			}
			public String getVideoPath() {
				return videoPath;
			}
			public void setVideoPath(String videoPath) {
				this.videoPath = videoPath;
			}
		}
		private ConvertResult convertQualityBased(DougaSystem system,String ffmpegPath,File pcm,double fps,String videoCodec,String audioCodec,File tmpOutput){
			ConvertResult converResult=new ConvertResult();
			try {
				if(processVideo){
				dougaLogger.trace(Messages.getString("log.create_video_sequence"));
				VideoOutInfo[] infos=system.getVideoSystem().writeDatas(workingDir);
				if(isCanceling()){
					
					return converResult;
				}
				dougaLogger.trace(Messages.getString("log.insert_item_and_effect"));
				system.getVideoSystem().writeItemAndEffect(workingDir, infos);
				if(isCanceling()){
					
					return converResult;
				}
				converResult.setVideoPath(workingDir.getAbsolutePath());
				}
				
				if(processAudio){
				dougaLogger.trace(Messages.getString("log.create_audio_sequence"));
				bout = new BufferedOutputStream(new FileOutputStream(pcm));
				system.getAudioSystem().writeDatas(bout);
				if(isCanceling()){
					return converResult;
					}
				converResult.setAudioPath(pcm.getAbsolutePath());
				}
			} catch (IOException e) {
				dougaLogger.error(e.getMessage());
				e.printStackTrace();
			}
			if(isCanceling()){
				
				return converResult;
			}
			
			/*
			
			*/
			
			
			converResult.setSuccessed(true);
			
			return converResult;
		}

	}
	
	
	
	public class OverwriteCheck implements FileStatusChangeListener{

		public void addList(FileStatusChangeEvent event) {
			File f=new File(event.getFilePath());
			if(f.exists()){
				FileOverwriteControler controler=new FileOverwriteControler(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),FileOverwriteControler.MODE_YES_NO_CANCEL);
				boolean r=controler.canOverwrite(f);
				System.out.println(r);
				if(r==false){
					//System.out.println(((FileDirChoicer)event.getSource()).getAbsoluteFilePath());
					((FileDirChoicer)event.getSource()).removePath();//cancel
				}
			}
		}

		public void removeList(FileStatusChangeEvent event) {
			
		}
		
	}
	
	public class FileSelected implements FileStatusChangeListener{

		public void addList(FileStatusChangeEvent event) {
			
			textDougaExecute.updateControlSwitch();
			updatePlayButton();
		}

		public void removeList(FileStatusChangeEvent event) {
			textDougaExecute.updateControlSwitch();
			updatePlayButton();
		}
		
	}
	
	public void updatePlayButton(){//TODO support audioonly
		boolean status=true;
		if(outputFileChooser.getFile()==null|| !outputFileChooser.getFile().exists()){
			status=false;
		}
		String aviPath=outputFileChooser.getAbsoluteFilePath()+"\\"+baseName.getText()+".avi";
		if(!new File(aviPath).exists()){
			status=false;
		}
		log.trace(status+","+aviPath);
		playButton.setEnabled(status);
	}

	public class TextDougaApplication extends RCPFileApplication{

		@Override
		protected void execNew() {
			dougaText.getTextWidget().setText("");
			textDougaApplication.setNeedSave(false);
			fileNameText.setText("");
			
			baseName.setText(jp.sourceforge.akjrcp.text_douga.rcp.Messages.getString("textdouga.default_export_video"));
		}

		@Override
		protected void execOpen() {
			File file=this.getFile();
			try {
				String text=IOUtils.toString(new FileInputStream(file));
				//text=text.replaceAll("\n", "\r\n");
				
				dougaText.getTextWidget().setText(text);
				textDougaApplication.setNeedSave(false);
				fileNameText.setText(file.getName());
				
				//set exportPath
				String name=FileNameUtils.getRemovedExtensionName(file.getName());
				
				baseName.setText(name);
				textDougaExecute.updateControlSwitch();
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		@Override
		protected void execSave() {
			String text=dougaText.getTextWidget().getText();
			text=TextUtils.changeLineSeparator(text);
			
			File file=this.getFile();
			try {
				byte[] bts=text.getBytes("MS932");
				FileUtils.writeStringToFile(file, text);
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			//update base name
			String name=FileNameUtils.getRemovedExtensionName(file.getName());
			baseName.setText(name);
			fileNameText.setText(file.getName());
		}

		@Override
		protected void saveStatusChanged() {
			log.trace("status:"+this.isNeedSave());
			saveButton.setEnabled(this.isNeedSave());
		}
		

	}
	
	private void insertFilePathLine(File file){
		dougaText.getTextWidget().insert(file.getAbsolutePath()+"\r\n");
	}
	public void updateUndoRedo() {
		undoButton.setEnabled(undoMan.undoable());
		redoButton.setEnabled(undoMan.redoable());
	}

}
